/**
 * @version 0.0.2
 * @type {{ws: null, options: null, init: communication.init, send: communication.send, sendFile: communication.sendFile}}
 */

var communication = {
    ws: null,
    options: null,
    /**
     *
     * @param options object参数  需要 wsurl websocket连接地址；
     *                                url  服务器地址
     *                                token  连接授权
     *                                onmessage 收到消息时的处理方法 参数data 即为接受到的参数（json格式）
     */
    init: function (options) {
        if (null == options) {
            console.error("参数不能为空");
            return;
        }
        if (options.wsurl == null || '' == options.wsurl) {
            console.error("url参数不能为空");
            return;
        }
        if (options.token == null || '' == options.token) {
            console.error("token参数不能为空");
            return;
        }
        if (options.onmessage == null) {
            console.error("onmessage参数不能为空");
            return;
        }
        ws = new WebSocket(options.wsurl + "?token=" + options.token);
        communication.options = options;
        var heartCheck = {
            timeout: 60000,//60s
            timeoutObj: null,
            serverTimeoutObj: null,
            reset: function () {
                //收到websocket消息,重置心跳检测定时器
                clearTimeout(this.timeoutObj);
                clearTimeout(this.serverTimeoutObj);
                this.start();
            },
            start: function () {
                //心跳检测,60s内没有收到服务器消息,会向服务器发送一条心跳消息,发送之后60s收不到服务器消息则重连
                var self = this;
                this.timeoutObj = setTimeout(function () {
                    var object = {};
                    object.code = 200;
                    ws.send(JSON.stringify(object));
                    self.serverTimeoutObj = setTimeout(function () {
                        ws.close();//如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                    }, self.timeout)
                }, this.timeout)
            },
        };

        initWs();

        function initWs() {
            ws.onopen = function () {
                //心跳检测
                reconnet = true;
                heartCheck.start();
            };
            ws.onmessage = function (event) {
                //收到服务端消息,重置心跳定时器
                heartCheck.reset();
                var data = JSON.parse(event.data);
                if (data.code == 200) {
                    //心跳消息不需要
                    console.log("心跳检测消息");
                    return;
                }
                if (data.code >= 400) {
                    //大于等于400的code属于异常，需要主动断开websocket连接
                    console.error("异常消息" + event.data);
                    ws.onclose = null;
                    ws.onerror = null;
                    clearTimeout(heartCheck.timeoutObj);
                    clearTimeout(heartCheck.serverTimeoutObj);
                }
                options.onmessage(event.data);
            };
            ws.onclose = function () {
                //close时重新连接
                if (reconnet) {
                    reconnect();
                }
            };
            ws.onerror = function () {
                //错误时重新连接
                if (reconnet) {
                    reconnect();
                }
            };
        }


        function reconnect() {
            //重现连接代码
            ws.onopen = null;
            ws.onmessage = null;
            ws.onclose = null;
            ws.onerror = null;
            clearTimeout(heartCheck.timeoutObj);
            clearTimeout(heartCheck.serverTimeoutObj);
            reconnet = false;
            ws = new WebSocket(options.wsurl + "?token=" + options.token);
            initWs();
        }
    },
    /**
     * 消息发送方法
     * @param data object对象
     *             code:消息区分代码
     *             type:消息类型(默认text,可缺省,video,image..)
     *             to:消息接收者
     *             text:消息正文
     */
    send: function (data) {
        if (ws == null) {
            console.error("未初始化ws");
            return;
        }
        ws.send(data);
    },
    /**
     * 消息发送方法(带文件参数的消息)
     * @param data object对象
     *             code:消息区分代码
     *             type:消息类型(text,video,image..)
     *             to:消息接收者
     *             from:消息发送者(可缺省)
     *             text:消息正文
     *             files:附属文件列表(array数组)
     */
    sendFile: function (data) {
        if (communication.options == null || null == communication.options.token || '' == communication.options.token) {
            console.error("token参数未初始化");
            return;
        }
        if (ws == null) {
            console.error("未初始化ws");
            return;
        }
        var formData = new FormData();
        if ((data.files == null || '' == data.files)) {
            console.error("files不能为空");
            return;
        }
        if (Object.prototype.toString.call(data.files) != '[object Array]') {
            console.error("files必须是数组格式");
            return;
        }
        for (var key in data) {
            if ("files" == key) {
                var files = data[key];
                for (var i = 0; i < files.length; i++) {
                    formData.append("files[]", files[i]);
                }
            } else {
                formData.append(key, data[key]);
            }
        }

        formData.append("token", communication.options.token);
        var XHR = null;
        if (window.XMLHttpRequest) {
            // 非IE内核
            XHR = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            // IE内核，这里早期IE版本不同，具体可以查下
            XHR = new ActiveXObject("Microsoft.XMLHTTP");
        } else {
            XHR = null;
        }
        if (XHR) {
            XHR.open("POST", url + "/message/sendMsg-file");
            XHR.onreadystatechange = function () {
                if (XHR.readyState == 4 && XHR.status == 200) {
                    var resultValue = XHR.responseText;
                    var data = JSON.parse(resultValue);
                    if (null == data.success || !data.success) {
                        console.error(resultValue);
                    }
                    XHR = null;
                }
            };
            XHR.send(formData);
        }
    }
};
